<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        ul,
        ol {
            list-style: none;
            position: absolute;
        }

        a {
            text-decoration: none;
            width: 30px;
            height: 50px;
            position: absolute;
            background: rgba(100, 100, 100, .7);
            font-size: 40px;
            text-align: center;
            line-height: 50px;
            font-family: '宋体';
            color: #fff;
        }

        #prev {
            left: 0;
            top: 225px;
        }

        #next {
            right: 0;
            top: 225px;
        }

        #box {
            width: 850px;
            height: 500px;
            position: relative;
            margin: 200px auto;
            overflow: hidden;
        }

        #box .img li {
            height: 500px;
        }

        #box .btn {
            right: 50px;
            bottom: 20px;
        }

        #box .btn li {
            width: 20px;
            height: 20px;
            float: left;
            background: #fff;
            margin-right: 5px;
            text-align: center;
            line-height: 20px;
            cursor: pointer;
        }

        #box .btn .ac {
            background: red;
            color: #fff;
        }
    </style>
</head>

<body>
    <div id="box">
        <ul class="img">
            <li><img src="images/1.jpg" alt=""></li>
            <li><img src="images/2.jpg" alt=""></li>
            <li><img src="images/3.jpg" alt=""></li>
            <li><img src="images/4.jpg" alt=""></li>
            <li><img src="images/5.jpg" alt=""></li>
        </ul>
        <ol class="btn"></ol>
        <a href="javascript:;" id='prev'>&laquo;</a>
        <a href="javascript:;" id='next'>&raquo;</a>
    </div>
    <script>
        class carousel {
            constructor() {
                this.box = document.querySelector('#box');
                this.ul = this.box.querySelector('.img');
                this.imgs = this.ul.querySelectorAll('li');
                this.ol = this.box.querySelector('.btn');
                this.prev = document.querySelector('#prev');
                this.next = document.querySelector('#next');
                this.init();
                this.bindEvents();
                this.autoPlay();
            }
            init() {
                this.len = this.imgs.length;
                this.height = this.imgs[0].offsetHeight;
                this.btns = new Array();
                this.index = 0;
                this.lastIndex = 0;
                this.isMove = false;
                this.timer;
                this.ul.appendChild(this.imgs[0].cloneNode(true));
                for (let i = 0; i < this.len; i++) {
                    var li = document.createElement('li');
                    if (i === 0) li.className = 'ac';
                    li.innerHTML = i + 1;
                    this.ol.appendChild(li);
                    this.btns.push(li);
                    li.onclick = () => {
                        if (!this.isMove) {
                            this.isMove = true;
                            this.lastIndex = this.index;
                            this.index = i;
                            this.move(this.index);
                            this.btns[this.lastIndex].classList.remove('ac');
                            this.btns[this.index].classList.add('ac');
                        }
                    }
                }
            }
            bindEvents() {
                this.prev.onclick = () => {
                    this.goPrev();
                }
                this.next.onclick = () => {
                    this.goNext()
                };
                this.box.onmouseenter = () => {
                    this.parse()
                };
                this.box.onmouseleave = () => {
                    this.autoPlay()
                };
            }
            goPrev() {
                if (!this.isMove) {
                    this.isMove = true;
                    this.lastIndex = this.index;
                    this.index--;
                    if (this.index < 0) {
                        this.index = this.len - 1;
                        this.ul.style.top = -this.len * this.height + 'px';
                    }
                    this.move(this.index);
                    this.btns[this.lastIndex].classList.remove('ac');
                    this.btns[this.index].classList.add('ac');
                }
            }
            goNext() {
                if (!this.isMove) {
                    this.isMove = true;
                    this.lastIndex = this.index;
                    this.index++;
                    if (this.index === this.len) {
                        this.index = 0;
                        this.move(this.len, () => {
                            this.ul.style.top = '0px';
                        })
                    } else {
                        this.move(this.index);
                    }
                    this.btns[this.lastIndex].classList.remove('ac');
                    this.btns[this.index].classList.add('ac');
                }
            }

            autoPlay() {
                this.timer = setInterval(() => {
                    this.goNext();
                }, 2500)
            }
            parse() {
                clearInterval(this.timer);
            }
            move(n, fn) {
                var start = this.ul.offsetTop;
                var stop = -n * this.height;
                this.ul.timer = setInterval(() => {
                    var dis = stop - start;
                    var speed = dis > 0 ? Math.ceil(dis / 10) : Math.floor(dis / 10);
                    start += speed;
                    this.ul.style.top = start + 'px';
                    if (start === stop) {
                        clearInterval(this.ul.timer);
                        this.isMove = false;
                        fn && fn();
                    }
                }, 30);
            }
        }
        new carousel();
    </script>
</body>

</html>